using System;
namespace Lizk.SimpleHUD
{
    [Serializable]
    public class HUDTwistList : HUDContainerSimple
    {
        protected HUDContainerSimple list;
        protected int selectedIndex = 0;
        [NonSerialized]
        protected bool moving;
        public float Padding { get; set; }
        public PointS Offset { get; set; }
        public float LeftMargin { get; set; }
        public float RightMargin { get; set; }
        public HUDImage LeftArrow { get; private set; }
        public HUDImage RightArrow { get; private set; }

        public event EventHandler<SelectionEventArgs> SelectedIndexChanged;
        public event EventHandler SelectedStoppedMoving;


        public HUDTwistList()
        {
            Padding = 5f;
            LeftMargin = 5f;
            RightMargin = 5f;
            list = new HUDContainerSimple()
            {
                Size = Size,
                Anchor = Anchor.All
            };

            LeftArrow = new HUDImage("back.png");

            RightArrow = new HUDImage("select.png");

            base.Add(list);
            base.Add(LeftArrow);
            base.Add(RightArrow);
        }

        public virtual int SelectedIndex
        {
            get
            {
                return selectedIndex;
            }
            set 
            {
                if (selectedIndex != value)
                {
                    int old = selectedIndex;
                    selectedIndex = value;
                    MoveItems(true);

                    if (old != selectedIndex && SelectedIndexChanged != null)
                        SelectedIndexChanged(this, new SelectionEventArgs(old, true));

                }
            }
        }

        public virtual void SetSelectedIndex(int value, bool animate)
        {
            int old = selectedIndex;
            selectedIndex = value;
            MoveItems(animate);

            if (old != selectedIndex && SelectedIndexChanged != null)
                SelectedIndexChanged(this, new SelectionEventArgs(old, animate));

        }


        public T GetSelectedControl<T>() where T : HUDControl
        {
            return (T)list[selectedIndex];
        }

        public HUDControl SelectedControl
        {
            get { if (selectedIndex >= 0 && selectedIndex < list.Count) return list[selectedIndex]; else return null; }
        }

        public override void Add(HUDControl item)
        {
            list.Add(item);
        }

        public override void Clear()
        {
            list.Clear();
        }

        public override T Get<T>(int index)
        {
            return list.Get<T>(index);
        }

        public override bool Contains(HUDControl item)
        {
            return list.Contains(item);
        }

        public override int Count
        {
            get
            {
                return list.Count;
            }
        }

        public override void AddRange(params HUDControl[] items)
        {
            list.AddRange(items);
        }

        public override void AddRange(System.Collections.Generic.ICollection<HUDControl> items)
        {
            list.AddRange(items);
        }
        public override bool Remove(HUDControl item)
        {
            return list.Remove(item);
        }

        

        public override void Update(TimeSpan ts)
        {
            base.Update(ts);

            if (moving)
            {



                if (SelectedControl == null)
                    moving = false;
                else
                {
                    if (!SelectedControl.IsMoving)
                    {
                        moving = false;
                        if (SelectedStoppedMoving != null)
                             SelectedStoppedMoving(this, null);
                    }
                }
            }

        }

        public virtual void MoveItems(bool animate)
        {
            // Cap the selectedindex within the indices of the list
            if (selectedIndex < 0)
                selectedIndex = 0;

            if (selectedIndex >= list.Count)
                selectedIndex = list.Count - 1;
            
            // Set position and size of Left Arrow
            LeftArrow.Size = new SizeS(LeftMargin, Size.Height);
            LeftArrow.Location = new PointS(Offset.X - LeftArrow.Size.Width - Padding / 2f, 0);
            if (selectedIndex == 0 || list.Count == 0)
            {
                if (animate)
                    LeftArrow.Fade(0, 6f);
                else
                    LeftArrow.Alpha = 0;
            }
            else
                if (animate)
                    LeftArrow.Fade(127, 6f);
                else
                    LeftArrow.Alpha = 127;



            // First set the positions of selectedIndex -> Count - 1
            PointS currentPosition = Offset;
            for (int i = selectedIndex; i < list.Count; i++)
            {
                if (animate)
                {
                    list[i].Destination = currentPosition;
                }
                else
                {
                    list[i].Location = currentPosition;
                }
                currentPosition += new PointS(list[i].Size.Width + Padding, 0);
                if (i == selectedIndex)
                    currentPosition += new PointS(RightMargin, 0);
            }

            // Then set positions of selectedIndex-1 -> 0
            currentPosition = Offset - new PointS(LeftMargin, 0);
            for (int i = selectedIndex - 1; i >= 0; i--)
            {
                currentPosition -= new PointS(list[i].Size.Width + Padding, 0);
                if (animate)
                {
                    list[i].Destination = currentPosition;
                }
                else
                {
                    list[i].Location = currentPosition;
                }
            }

            if (SelectedControl != null)
            {
                if (!animate && SelectedStoppedMoving != null)
                    SelectedStoppedMoving(this, null);
                else
                    moving = true;

                // Set position and size of RightArrow
                RightArrow.Size = new SizeS(RightMargin, Size.Height);
                PointS rightArrowPosition = new PointS(Offset.X + Padding / 2f + SelectedControl.Size.Width, 0);
                if (animate)
                    RightArrow.Destination = rightArrowPosition;
                else
                    RightArrow.Location = rightArrowPosition;

                if (selectedIndex == list.Count - 1 || list.Count == 0)
                {
                    if (animate)
                        RightArrow.Fade(0, 6f);
                    else
                        RightArrow.Alpha = 0;
                }
                else
                {
                    if (animate)
                        RightArrow.Fade(127, 6f);
                    else
                        RightArrow.Alpha = 127;
                }
            }
            else
            {
                RightArrow.Alpha = LeftArrow.Alpha = 0;
            }



        }
        
    }

}
